package com.zmm.myyimixian.widget;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Administrator on 2016/10/23 0023.
 * 自定义流式布局
 */

public class FlowLayout extends ViewGroup {
    //存储所有行的view视图  按行纪录view  每行的view存储到list集合中
    private List<List<View>> mAllChildViews=new ArrayList<>();
    //纪录每行的最大高度
    private List<Integer> mLineHeight=new ArrayList<>();

    public FlowLayout(Context context) {
        super(context);
    }

    public FlowLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    /**
     * 负责子控件的测量模式和大小 根据所有的子控件的设置确定viewgroup自己的宽度和高度
     *  首先得到父容器传入的测量模式和宽高的计算值 循环所有的子view 调用measureChild对
     *  所有的子view进行测量 然后根据所有的子view测量得出宽度和高度  如果viewgroup设置为
     *  warp_content时 viewgroup的宽度和子view的总宽度一致  高度和子view的最大的高度一致
     *
     *  如果viewgroup设置为match_parent时直接根据父viewgroup传入的宽度和高度进行测量设置
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int widthMode=MeasureSpec.getMode(widthMeasureSpec);
        int heightMode=MeasureSpec.getMode(heightMeasureSpec);
        int widthSize=MeasureSpec.getSize(widthMeasureSpec);
        int heightSize=MeasureSpec.getSize(heightMeasureSpec);

        //定义一个不断累加的总高度 当布局中高度的设置为warp_content时使用该高度
        int totalHeight=0;
        //定义不断累加的变量  存放当前行控件的宽度总和
        int lineWidth=0;
        //获取当前行控件中最高的控件的高度总和
        int lineHeight=0;
        //获取viewGroup中子控件总个数遍历
        int childCount=getChildCount();
        for(int i=0;i<childCount;i++){
            View childView=getChildAt(i);
            //测量子控件的宽度和高度
            measureChild(childView,widthMeasureSpec,heightMeasureSpec);
            //获取每个子控件的布局参数
            MarginLayoutParams lp= (MarginLayoutParams) childView.getLayoutParams();
            //获取子控件的实际宽度和高度
            int childWidth=childView.getMeasuredWidth()+lp.leftMargin+lp.rightMargin;
            int chileHeight=childView.getMeasuredHeight()+lp.topMargin+lp.bottomMargin;

            //如果加入当前的childView超出最大的宽度  到目前为止最大的宽度给width 累加高度 开启新行
            if(lineWidth+childWidth>widthSize){
                //开启新行
                lineWidth=childWidth;
                //累加高度
                totalHeight+=lineHeight;
                lineHeight=chileHeight;//开启纪录下一行的高度
            }else{
                //累加lineWidth  取得最大的lineHeight
                lineWidth+=childWidth;
                lineHeight=Math.max(lineHeight,chileHeight);
            }

            //如果绘制最后一个
            if(i==childCount-1){
                totalHeight+=lineHeight;
            }

            setMeasuredDimension(widthSize,
                    (heightMode==MeasureSpec.EXACTLY)?heightSize:totalHeight);
        }
    }

    @Override
    protected LayoutParams generateDefaultLayoutParams() {
        return new MarginLayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT);
    }

    @Override
    public LayoutParams generateLayoutParams(AttributeSet attrs) {
        return new MarginLayoutParams(getContext(),attrs);
    }

    @Override
    protected LayoutParams generateLayoutParams(LayoutParams p) {
        return new MarginLayoutParams(p);
    }

    /**
     * 完成对viewgroup中所有childview的位置的指定
     */
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        mAllChildViews.clear();
        mLineHeight.clear();
        //获取当前view的宽度
        int layoutWidth=getWidth();
        //声明变量 定义每行的宽度和高度
        int lineWidth=0;
        int lineHeight=0;
        //声明list集合存储每一行中所有的childView
        List<View> lineViews=new ArrayList<>();
        int childCount=getChildCount();
        for(int i=0;i<childCount;i++){
            View childView=getChildAt(i);
            MarginLayoutParams lp= (MarginLayoutParams) childView.getLayoutParams();
            int childWidth=childView.getMeasuredWidth()+lp.leftMargin+lp.rightMargin;
            int childHeight=childView.getMeasuredHeight()+lp.topMargin+lp.bottomMargin;
            //如果需要换行
            if(lineWidth+childWidth>layoutWidth){
                //纪录这一行中所有的view以及最大高度
                mLineHeight.add(lineHeight);
                //将每一行的childview视图存储到集合中  然后开启新的arraylist纪录下一行
                mAllChildViews.add(lineViews);
                lineWidth=0;//重置行宽度
                lineViews=new ArrayList<>();
            }
            //如果不需要换行 则累加
            lineWidth+=childWidth;
            lineHeight=Math.max(lineHeight,childHeight);
            lineViews.add(childView);
        }

        mLineHeight.add(lineHeight);
        mAllChildViews.add(lineViews);

        int mLeft=0;
        int mTop=0;
        int lineNums=mAllChildViews.size();//获取总行数
        for(int i=0;i<lineNums;i++){
            lineViews=mAllChildViews.get(i);//获取每一行中所有的view
            lineHeight=mLineHeight.get(i);//当前行的最大高度
            for(int j=0;j<lineViews.size();j++){
                View childView=lineViews.get(j);
                MarginLayoutParams lp= (MarginLayoutParams) childView.getLayoutParams();
                //计算childView中的left top right bottom
                int left_child=mLeft+lp.leftMargin;
                int top_child=mTop+lp.topMargin;
                int right_child=left_child+childView.getMeasuredWidth();
                int botton_child=top_child+childView.getMeasuredHeight();
                childView.layout(left_child,top_child,right_child,botton_child);
                //指定每个子控件的起始位置
                mLeft+=childView.getMeasuredWidth()+lp.leftMargin+lp.rightMargin;
            }
            //下一行
            mLeft=0;
            mTop+=lineHeight;
        }
    }
}






